package com.sz.app.oss.api.system;

import com.sz.app.oss.constants.MessagesCodes;
import com.sz.app.oss.constants.Permissions;
import com.sz.app.oss.exception.ErrorCodes;
import com.sz.biz.app.web.BaseController;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.BizException;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.core.service.role.MembershipType;
import com.sz.common.core.service.role.RoleMembership;
import com.sz.common.core.system.entity.Authorization;
import com.sz.common.core.system.entity.Role;
import com.sz.common.core.system.service.AuthorizationService;
import com.sz.common.core.system.service.RoleService;
import com.sz.app.oss.system.RoleAggregationService;
import com.sz.app.oss.api.system.dto.AssignMemberDto;
import com.sz.app.oss.api.system.dto.DragDto;
import com.sz.app.oss.api.system.dto.PermissionDto;
import com.sz.app.oss.api.system.dto.RoleDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.List;

/**
 * Created by penghui.zheng <br> on 2016/10/27.
 */
@Controller
@RequestMapping("/api/v1/sys/roles")
@Api(description = " ", tags = "004、角色管理")
public class RoleController extends BaseController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleAggregationService roleAggregationService;

    @Autowired
    AuthorizationService authorizationService;

    /**
     * 新建一个角色
     *
     * @throws Exception
     */
    @ApiOperation(value = "新建角色", notes = "新建角色<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({@ApiImplicitParam(name = "roleDto", value = "提交角色信息\r\n "
            + "roleName,roleCode,description", required = true, dataType = "RoleDto", paramType = "body")})
    @RequestMapping(value = "", method = {RequestMethod.POST})
    @RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto saveRole(@RequestBody RoleDto roleDto, HttpServletRequest request) {
        if (roleDto.getName() == null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_MODEL_ROLE_ROLENAME_NULL, roleDto.getName());
        }
        if (roleDto.getCode() == null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_MODEL_ROLE_ROLECODE_NULL, roleDto.getCode());
        }
        Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);
        int roleId = roleService.saveRole(role);
        ResultDto dto = getSaveSuccessDto(MessagesCodes.MODULE_ROLE);
        dto.setData(roleId);
        return dto;
    }

    /**
     * 保存角色的权限
     *
     * @throws Exception
     */
    @ApiOperation(value = "保存角色的权限", notes = "保存角色的权限<br>权限：" + Permissions.SYS_MGT_ROLE)
    @RequestMapping(value = "/saveRolePermission", method = {RequestMethod.POST})
    @RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto saveRolePermission(@RequestBody List<PermissionDto> list) {
        if (list != null && list.size() > 0) {
            for (PermissionDto permissionDto : list) {
                Authorization authorization = new Authorization();
                authorization.setPermissionId(permissionDto.getPermissionId());
                authorization.setRoleId(permissionDto.getRoleId());
                authorization.setResType(permissionDto.getResType());
                authorizationService.save(authorization);
            }

        }
        ResultDto dto = getOperateSuccessDto(MessagesCodes.ROLE_SAVE_PERMISSION_SUCCESS);
        return dto;
    }

    /**
     * 根据角色Id删除角色 ,逻辑删除
     *
     * @throws Exception
     */
    @ApiOperation(value = "删除一个角色", notes = "非物理删除 打标志 不允许使用<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色的id ", required = true, dataType = "int", paramType = "path")})
    @RequestMapping(value = "/{id}", method = {RequestMethod.DELETE})
    @RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto deleteRole(@PathVariable int id, HttpServletRequest request) {
        roleService.deleteRoleById(id);
        ResultDto dto = getDeleteSuccessDto(MessagesCodes.MODULE_ROLE);
        dto.setData(id);
        return dto;
    }

    /**
     * 根据角色Id查询角色
     *
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色的id ", required = true, dataType = "int", paramType = "path")})
    @RequestMapping(value = "/{id}", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto getRoleById(@PathVariable int id) {
        Role role = roleService.findByRoleId(id);
        ResultDto dto = new ResultDto();
        dto.setData(role);
        return dto;
    }

    /**
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "domainId", value = "系统域值domainId ", required = true, dataType = "int", paramType = "path")})
    @RequestMapping(value = "/code/{domainId}", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto getRoleCode(@PathVariable int domainId) {
        Role role = roleService.getRoleCode(domainId);
        ResultDto dto = new ResultDto();
        dto.setData(role);
        return dto;
    }

    /**
     * 根据查询条件获取角色列表
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索角色", notes = "搜索角色，返回角色列表，支持分页")
    @ApiImplicitParams({@ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小，max2000", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "domainId", value = "域值", required = true, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/search", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto getRoles(@RequestParam String q, @RequestParam int pageIndex,
                       @RequestParam int pageSize, @RequestParam int domainId) {
        List<ParamData> list = roleService.roleListPage(q, pageIndex, pageSize, domainId);
        ResultDto dto = new ResultDto();
        dto.setData(list);
        return dto;
    }

    /**
     * 修改角色
     *
     * @throws Exception
     */
    @ApiOperation(value = "修改角色", notes = "修改角色<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "修改角色的id ", required = true, dataType = "int", paramType = "path"),
            @ApiImplicitParam(name = "RoleDto", value = "提交角色信息\r\n "
                    + "roleName,roleCode,description", required = true, dataType = "RoleDto", paramType = "body")})
    @RequestMapping(value = "/{id}", method = {RequestMethod.PUT})
    @RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto updateRole(@PathVariable int id, @RequestBody RoleDto roleDto) {
        Role role = new Role();
        BeanUtils.copyProperties(roleDto, role);
        role.setId(id);
        int flag = roleService.updateRole(role);
        ResultDto dto = getUpdateSuccessDto(MessagesCodes.MODULE_ROLE);
        dto.setData(flag);
        return dto;
    }

    /**
     * 拖动角色
     *
     * @throws Exception
     */
    @ApiOperation(value = "拖动角色", notes = "拖动角色<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "拖动当前角色的id", required = true, dataType = "int", paramType = "path"),
            @ApiImplicitParam(name = "DragDto", value = "提交拖动信息\r\n "
                    + "targetpreid,domainId", required = true, dataType = "DragDto", paramType = "body")})
    @RequestMapping(value = "/drag/{id}", method = {RequestMethod.PUT})
    @RequiresPermissions(value = {Permissions.SYS_MGT_ROLE})
    public
    @ResponseBody
    ResultDto dragRole(@PathVariable int id, @RequestBody DragDto dragDto) {
        Integer targetpreid = dragDto.getTargetpreid();
        Integer domainId = dragDto.getDomainId();
        roleService.dragRole(id, targetpreid, domainId);
        ResultDto dto = getOperateSuccessDto(MessagesCodes.ROLE_DRAG_SUCCESS);
        dto.setData(id);
        return dto;
    }

    /**
     * 根据组织机构Id查询角色
     *
     * @throws Exception
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orgId", value = "组织机构的id ", required = true, dataType = "int", paramType = "path")})
    @RequestMapping(value = "/orgId/{orgId}", method = {RequestMethod.GET})
//	@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto findByOrgId(@PathVariable int orgId) {
        List<Role> list = roleService.getRoleByMember(new RoleMembership(orgId, MembershipType.ORGANIZATION));
        ResultDto dto = new ResultDto();
        dto.setData(list);
        return dto;
    }

    /**
     * 角色分配成员
     *
     * @throws BizException
     * @throws ParseException
     */
    @ApiOperation(value = "角色分配成员", notes = "角色分配成员<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleid", value = "角色id", required = true, dataType = "int", paramType = "path"),
            @ApiImplicitParam(name = "members", value = "-", required = true, dataType = "AssignMemberDto", paramType = "body")})
    @RequestMapping(value = "/{roleid}/assignmembers", method = {RequestMethod.PUT})
    @RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto assignRoleMembers(@PathVariable int roleid,
                                @RequestBody AssignMemberDto assignMemberDto) {
        List<RoleMembership> memberships = assignMemberDto.getRoleMemberships();
        roleService.assignRoleMembers(roleid, memberships);
        ResultDto dto = getOperateSuccessDto(MessagesCodes.ROLE_ASSIGN_MEMBERS_SUCCESS);
        dto.setData(roleid);
        return dto;
    }

    /**
     * 角色删除成员
     *
     * @throws BizException
     * @throws ParseException
     */
    @ApiOperation(value = "角色删除成员", notes = "角色删除成员<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleid", value = "角色id", required = true, dataType = "int", paramType = "path"),
            @ApiImplicitParam(name = "orgIds", value = "-", required = true, dataType = "AssignMemberDto", paramType = "body")})
    @RequestMapping(value = "/{roleid}/removemembers", method = {RequestMethod.PUT})
    @RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto removeRolemembers(@PathVariable int roleid,
                                @RequestBody AssignMemberDto assignMemberDto) {
        List<RoleMembership> memberships = assignMemberDto.getRoleMemberships();
        roleService.removeRoleMembers(roleid, memberships);
        ResultDto dto = getOperateSuccessDto(MessagesCodes.ROLE_REMOVE_MEMBERS_SUCCESS);
        dto.setData(roleid);
        return dto;
    }

    /**
     * 角色删除组织
     *
     * @throws BizException
     * @throws ParseException
     */
    /*
	 * @ApiOperation(value = "角色删除组织", notes = "角色删除组织")
	 * 
	 * @ApiImplicitParams({
	 * 
	 * @ApiImplicitParam(name = "roleid", value = "角色id", required = true,
	 * dataType = "int", paramType = "path"),
	 * 
	 * @ApiImplicitParam(name = "orgIds", value = "组织的id列表字符串,用','分割", required
	 * = true, dataType = "string", paramType = "body")})
	 * 
	 * @RequestMapping(value = "/{roleid}/removeorg", method =
	 * {RequestMethod.DELETE})
	 * 
	 * @RequiresPermissions(Permissions.SYS_MGT_ROLE) public
	 * 
	 * @ResponseBody ResultDto removeRoleOrgs(@PathVariable int roleid,
	 * 
	 * @RequestBody String orgIds) throws BizException, ParseException {
	 * roleService.removeRoleOrgs(roleid, orgIds); ResultDto dto = new
	 * ResultDto(); dto.setData(roleid); return dto; }
	 */

    /**
     * 角色删除用户
     *
     * @throws BizException
     * @throws ParseException
     */
	/*
	 * @ApiOperation(value = "角色删除用户", notes = "角色删除用户")
	 * 
	 * @ApiImplicitParams({
	 * 
	 * @ApiImplicitParam(name = "roleid", value = "角色id", required = true,
	 * dataType = "int", paramType = "path"),
	 * 
	 * @ApiImplicitParam(name = "orgIds", value = "组织的id列表字符串,用','分割", required
	 * = true, dataType = "string", paramType = "body")})
	 * 
	 * @RequestMapping(value = "/{roleid}/removeuser", method =
	 * {RequestMethod.DELETE})
	 * 
	 * @RequiresPermissions(Permissions.SYS_MGT_ROLE) public
	 * 
	 * @ResponseBody ResultDto removeRoleUsers(@PathVariable int roleid,
	 * 
	 * @RequestBody String orgIds) throws BizException, ParseException {
	 * roleService.removeRoleUsers(roleid, orgIds); ResultDto dto = new
	 * ResultDto(); dto.setData(roleid); return dto; }
	 */

    /**
     * 根据条件搜索角色下的用户和组织机构
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索角色下的用户和组织机构", notes = "角色下的用户和组织机构，返回用户和组织机构列表，支持分页<br>权限：" + Permissions.SYS_MGT_ROLE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色Id", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "roleType", value = "查询的关键字", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小，max2000", required = true, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/searchUserAndOrg", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto serchRoleListPage(@RequestParam Integer roleId,
                                @RequestParam(required = false) String q, @RequestParam(required = true) String roleType, @RequestParam int pageIndex, @RequestParam int pageSize) {

        return roleAggregationService.searchRoleListPage(roleId, q, roleType, pageIndex, pageSize);
    }

    /**
     * 异步校验角色名称
     */
    @ApiOperation(value = "异步校验角色名称", notes = "异步校验角色名称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "角色名称", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "id", value = "id", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "domainId", value = "域值", required = true, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/checkname", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto roleNameCheck(@RequestParam(required = true) String name, @RequestParam(required = false, defaultValue = "0") int id,
                            @RequestParam(required = true) String domainId) {
        roleService.checkRoleName(name, id, domainId);
        return new ResultDto();
    }

    /**
     * 异步校验角色编号
     */
    @ApiOperation(value = "异步校验角色编号", notes = "异步校验角色编号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "角色编号", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "id", value = "id", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "domainId", value = "域值", required = true, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/checkcode", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.SYS_MGT_ROLE)
    public
    @ResponseBody
    ResultDto roleCodeCheck(@RequestParam(required = true) String code, @RequestParam(required = false, defaultValue = "0") int id,
                            @RequestParam(required = true) String domainId) {
        roleService.checkRoleCode(code, id, domainId);
        return new ResultDto();
    }
}
